package roborally.Conditions;
import java.util.ArrayList;
import java.util.List;

import be.kuleuven.cs.som.annotate.Basic;
import roborally.*;

/**
 * A class of Energy-at-least-conditions for playing the roborally game, involving a final energy amount and a list of Energy-at-least conditions.
 * 
 * @version  2.90
 * @author   Michiel Ruelens & Dieter Naten
 */
public class Energy_at_least extends Condition {

	private final double energy; //in WATTSECONDS
	private static List<Energy_at_least> ealList = new ArrayList<Energy_at_least>();
	
	/**
	 * Create a new Energy-at-least. These objects check whether their given placeable 
	 * has a greater (or an equal) energy amount compared to the given parameter.
	 * @param energy
	 */
	private Energy_at_least(double energy){
		this.setStringForm("Energy-at-least "+energy+" Ws");
		this.energy = energy;
	}

	/**
	 * This method returns the Energy-at-least object. As there is no need to make duplicate objects that have the same parameter;
	 * all objects are kept in a list and if an object is required that has the same parameter as one that already exists,
	 * the existing one is returned.
	 */
	public static Energy_at_least getInstance(double energy) {
		for(Energy_at_least eal: ealList){
			if(eal.getEnergy() == energy){
				return eal;
			}
		}
		Energy_at_least newEal = new Energy_at_least(energy);
		Energy_at_least.ealList.add(newEal);
		return newEal;
	}

	/**
	 * This method is required as dictated by the superclass Condition, but in this class this method is replaced by the method
	 * getInstance(double energy).
	 */
	@Override
	public Condition getInstance() throws IllegalArgumentException {
		System.out.println("You must provide an argument which dictates the Energy that is at least required (in Ws).");
		throw new IllegalArgumentException();
	}
	
	/**
	 * Return the energy of this condition.
	 */
	@Basic
	private double getEnergy() {
		return energy;
	}
	
	
	/**
	 * Returns true if the placeable has an energy property and it's energy amount is greater
	 * than or equal to the field 'energy' (all in EnergyUnit.WATTSECOND).
	 */
	@Override
	public boolean validate(Placeable placeable) {
		boolean result = false;
		if(placeable instanceof Robot){
			if(((Robot) placeable).getEnergy() >= this.energy){
				result = true;
			}
		}
		else if(placeable instanceof Battery){
			if( ((Battery) placeable).getEnergy().toUnit(EnergyUnit.WATTSECOND).getNumeral() >= this.energy){
				result = true;
			}
		}
		else if(placeable instanceof RepairKit){
			if(((RepairKit) placeable).getEnergy().toUnit(EnergyUnit.WATTSECOND).getNumeral() >= this.energy){
				result = true;
			}	
		}
		return result;
	}
}
